package com.linkgie.galaxyframework.utils;

import java.util.Objects;
import java.util.regex.Pattern;

public class Version {

	public static final String VERSION_FORMAT_REGEX = "\\d+\\.\\d+\\.\\d+((\\.|-)\\w+)?";
	
	public static final Pattern STANDARD_REGEX = Pattern.compile("^"+VERSION_FORMAT_REGEX+"$");

	public static final Version DEBUG = parse("0.0.0");

	private static final String RELEASE_PHASE = "RELEASE";

	private static final String SNAPSHOT_PHASE = "SNAPSHOT";

	private Integer major;

	private Integer minor;

	private Integer revision;

	private String phase;

	private final boolean released;

	private final boolean snapshot;

	/**
	 * 主版本号；
	 * 
	 * @return
	 */
	public Integer getMajor() {
		return major;
	}

	/**
	 * 次版本号；
	 * 
	 * @return
	 */
	public Integer getMinor() {
		return minor;
	}

	/**
	 * 修订版本号；
	 * 
	 * @return
	 */
	public Integer getRevision() {
		return revision;
	}

	/**
	 * 阶段标识；
	 * 
	 * @return
	 */
	public String getPhase() {
		return phase;
	}

	/**
	 * 是否为正式版本；<p>
	 * 
	 * 即，阶段标识是否为 {@value #RELEASE_PHASE}；
	 * 
	 * @return
	 */
	public boolean isReleased() {
		return released;
	}

	/**
	 * 是否为快照版本；<p>
	 * 
	 * 即，阶段标识是否为 {@value #SNAPSHOT_PHASE}；
	 * 
	 * @return
	 */
	public boolean isSnapshot() {
		return snapshot;
	}

	private Version(int major, int minor, int revision, String phase) {
		this.major = major;
		this.minor = minor;
		this.revision = revision;
		this.phase = phase;
		this.released = phase != null && RELEASE_PHASE.equalsIgnoreCase(phase);
		this.snapshot = phase != null && SNAPSHOT_PHASE.equalsIgnoreCase(phase);
	}

	@Override
	public String toString() {
		String v = String.format("%s.%s.%s", major, minor, revision);
		if (phase == null) {
			return v;
		}
		if (isReleased()) {
			return v + "." + phase;
		}
		return v + "-" + phase;
	}

	/**
	 * 转换标准版本；
	 * <p>
	 * 
	 * 标准版本是匹配 {@link #STANDARD_REGEX} 正则表达式的字符串；
	 * <p>
	 * 
	 * 如果参数指定一个非标准版本，则返回 null ；
	 * 
	 * @param standardVersion
	 * @return
	 */
	public static Version parse(String standardVersion) {
		if (TextUtils.isBlank(standardVersion)) {
			return null;
		}
		String v = standardVersion.trim();
		if (!STANDARD_REGEX.matcher(v).matches()) {
			return null;
		}
		String[] sections = v.split("\\.");
		int major = Integer.parseInt(sections[0]);
		int minor = Integer.parseInt(sections[1]);
		int revision;
		String phase = null;
		if (sections.length == 3) {
			String last = sections[2];
			int indexOfPhase = last.indexOf("-");
			if (indexOfPhase > 0) {
				// 注：由于已经过正则表达式检查，因此如果存在，则 indexOfPhase 必定大于 0 ；
				revision = Integer.parseInt(last.substring(0, indexOfPhase));
				phase = last.substring(indexOfPhase + 1);
			} else {
				revision = Integer.parseInt(last);
			}
		} else {
			revision = Integer.parseInt(sections[2]);
			phase = sections[3];
		}

		Version version = new Version(major, minor, revision, phase);

		return version;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (obj instanceof Version) {
			Version oth = (Version) obj;
			if (this.major == oth.major && this.minor == oth.minor && this.revision == oth.revision
					&& Objects.equals(this.phase, oth.phase)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public int hashCode() {
		return Objects.hash(this.major, this.minor, this.revision, this.phase);
	}
}
